package net.cassandraview.config;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.annotation.PostConstruct;
import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

@ManagedBean(name = "configurationManager")
@ApplicationScoped
public class ConfigurationManager {
	
	protected static final Logger log = Logger.getLogger(ConfigurationManager.class.getName());
	
	protected static final String CONFIG_DIR = ".cassandraview";
	
	protected static final String MAIN_CONFIG = "config.xml";
	
	protected volatile Configuration config;
	
	@PostConstruct
	protected void init() {
		log.log(Level.INFO, "Initializing configuration");

		File configDir = new File(System.getProperty("user.home") + File.separator + CONFIG_DIR);
		File mainConfig = new File(configDir.getAbsolutePath() + File.separator + MAIN_CONFIG);
		try {
			if (!configDir.exists() || !mainConfig.exists() || !mainConfig.canRead())
				createDefault();
			Unmarshaller unm = JAXBContext.newInstance(Configuration.class).createUnmarshaller();
	        config = (Configuration) unm.unmarshal(new FileInputStream(mainConfig));
		} catch (IOException e) {
			log.log(Level.SEVERE, "IOexception while trying to create configuration.", e);
			log.log(Level.SEVERE, "Configuration cannot be created. Will continue to work with default in-memory config.");
			log.log(Level.SEVERE, "Configuration cannot be created. No configuration data will be stored on disk.");
		} catch (JAXBException e) {
			log.log(Level.SEVERE, "JAXBException while trying to create configuration.", e);
			log.log(Level.SEVERE, "Configuration cannot be parsed. Will continue to work with default in-memory config.");
			log.log(Level.SEVERE, "Configuration cannot be parsed. No configuration data will be stored on disk.");
		}
		
		log.log(Level.INFO, "Finished configuration initialization");
	}
	
	public Configuration getConfiguration() {
		return config;
	}
	
	public void refresh() {
		init();
	}
	
	protected void createDefault() throws IOException, JAXBException {
		File configDir = new File(System.getProperty("user.home") + File.separator + CONFIG_DIR);
		configDir.mkdir();
		File mainConfig = new File(configDir.getAbsolutePath() + File.separator + MAIN_CONFIG);
		mainConfig.createNewFile();
		Marshaller marshaller = JAXBContext.newInstance(Configuration.class).createMarshaller();
		config = new Configuration();
		Host local = new Host();
		local.setHost("localhost");
		local.setPort("9160");
		local.setJmxPort("7199");
		config.getHost().add(local);
		marshaller.marshal(config, mainConfig);
	}
}
 
